home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 June / EnigmA AMIGA RUN 19 (1997)(G.R. Edizioni)(IT)[!][issue 1997-06][EAR-CD III].iso / games / interactivefiction / agt / source / os_amiga.c < prev   
C/C++ Source or Header  |  1996-10-31  |  14KB  |  643 lines

  1. /* os_amiga.c -- Interface routine for the Amiga. */
  2. /*         Written by David Kinder.      */
  3.  
  4. #include <proto/asl.h>
  5. #include <proto/dos.h>
  6. #include <proto/exec.h>
  7. #include <proto/gadtools.h>
  8. #include <proto/icon.h>
  9. #include <proto/intuition.h>
  10. #include <exec/exec.h>
  11. #include <ctype.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <limits.h>
  15. #include <time.h>
  16. #include "agtread.h"
  17. #include "uagt.h"
  18.  
  19. #define SHIFT (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)
  20. #define HISTORY_SIZE 10
  21. enum chars
  22.   { CHAR_LEFT = 0x100,
  23.     CHAR_SHIFTLEFT,
  24.     CHAR_RIGHT,
  25.     CHAR_SHIFTRIGHT,
  26.     CHAR_UP,
  27.     CHAR_DOWN };
  28.  
  29. extern struct Library *IntuitionBase;
  30. struct Screen *Screen;
  31. struct Window *Window;
  32. struct Window *OldWindowPtr;
  33. struct RastPort *RPort;
  34. struct Menu *Menus;
  35. struct Process *ThisProcess;
  36. struct FileRequester *FileReq;
  37. APTR Visual;
  38. char *History[HISTORY_SIZE];
  39. char Version[] = "$VER:AGiliTy 0.3 (31.10.96)";
  40.  
  41. int scroll_count;
  42. int screen_height;
  43. int box,boxx;
  44.  
  45. void print_statline(void);
  46. void busy_pointer(int busy);
  47. void draw_cursor(void);
  48. void get_string(char *buffer, int len);
  49. void add_history(char *buffer);
  50. int use_history(char *buffer, int hpos, int left);
  51. void file_req(char *s,char *title,char *pattern,char *dir,ULONG save);
  52.  
  53. void agt_delay(int n)
  54. {
  55.   print_statline();
  56.   Delay(50*n);
  57. }
  58.  
  59. void agt_tone(int hz,int ms)
  60. {
  61. }
  62.  
  63. int agt_rand(int a,int b)
  64. {
  65.   return a+(rand()>>2)%(b-a+1);
  66. }
  67.  
  68. char *agt_input(int in_type)
  69. {
  70. char *s;
  71.  
  72.   scroll_count = 0;
  73.   print_statline();
  74.   s = rmalloc(256);
  75.   get_string(s,256);
  76.   if (script_on) fprintf(scriptfile,"%s",s);
  77.   agt_newline();
  78.   return s;
  79. }
  80.  
  81. char agt_getkey(bool echo_char)
  82. {
  83. char s[2];
  84. int c = 128;
  85.  
  86.   print_statline();
  87.   s[1] = '\0';
  88.   while (c >= 128) c = get_character();
  89.   if (echo_char && c > 32)
  90.   {
  91.     SetAPen(RPort,2);
  92.     s[0] = c;
  93.     agt_puts(s);
  94.     agt_newline();
  95.     SetAPen(RPort,1);
  96.   }
  97.   return c;
  98. }
  99.  
  100. void agt_textcolor(int c)
  101. {
  102.   switch (c)
  103.   {
  104.     case -1:
  105.       while ((RPort->AlgoStyle & FSF_BOLD) == 0)
  106.     SetSoftStyle(RPort,RPort->AlgoStyle|FSF_BOLD,AskSoftStyle(RPort));
  107.       break;
  108.     case -2:
  109.       while (RPort->AlgoStyle != 0)
  110.     SetSoftStyle(RPort,FS_NORMAL,AskSoftStyle(RPort));
  111.       break;
  112.   }
  113. }
  114.  
  115. void agt_statline(const char *s)
  116. {
  117. int x,y;
  118.  
  119.   SetAPen(RPort,2);
  120.   SetBPen(RPort,3);
  121.   x = RPort->cp_x;
  122.   y = RPort->cp_y;
  123.   Move(RPort,0,RPort->TxBaseline);
  124.   Text(RPort,s,strlen(s));
  125.   Move(RPort,x,y);
  126.   SetAPen(RPort,1);
  127.   SetBPen(RPort,0);
  128. }
  129.  
  130. void agt_clrscr(void)
  131. {
  132.   SetAPen(RPort,0);
  133.   RectFill(RPort,
  134.        0,RPort->TxHeight,
  135.        Window->Width-1,(screen_height*RPort->TxHeight)-1);
  136.   SetAPen(RPort,1);
  137.   Move(RPort,0,RPort->TxHeight);
  138.  
  139.   curr_x = 0;
  140.   if (script_on) fprintf(scriptfile,"\n\n\n\n");
  141.   scroll_count = 0;
  142. }
  143.  
  144. void agt_puts(const char *s)
  145. {
  146.   Move(RPort,RPort->cp_x,RPort->cp_y+RPort->TxBaseline);
  147.   Text(RPort,s,strlen(s));
  148.   Move(RPort,RPort->cp_x,RPort->cp_y-RPort->TxBaseline);
  149.   if (RPort->cp_x/RPort->TxWidth >= screen_width) RPort->cp_x = 0;
  150.  
  151.   curr_x = RPort->cp_x/RPort->TxWidth;
  152.   if (script_on) fprintf(scriptfile,"%s",s);
  153. }
  154.  
  155. void agt_newline(void)
  156. {
  157.   if (RPort->cp_y/RPort->TxHeight >= screen_height-1)
  158.   {
  159.     ClipBlit(RPort,0,RPort->TxHeight*2,
  160.          RPort,0,RPort->TxHeight,
  161.          Window->Width,(screen_height-2)*RPort->TxHeight,0xC0);
  162.     SetAPen(RPort,0);
  163.     RectFill(RPort,
  164.          0,(screen_height-1)*RPort->TxHeight,
  165.          Window->Width-1,(screen_height*RPort->TxHeight)-1);
  166.     SetAPen(RPort,1);
  167.     Move(RPort,boxx,(screen_height-1)*RPort->TxHeight);
  168.   }
  169.   else Move(RPort,boxx,RPort->cp_y+RPort->TxHeight);
  170.  
  171.   if (box == 0)
  172.   {
  173.     scroll_count++;
  174.     if (scroll_count >= screen_height-2)
  175.     {
  176.       Move(RPort,0,RPort->cp_y+RPort->TxBaseline);
  177.       Text(RPort,"  --MORE--",10);
  178.       Move(RPort,RPort->cp_x,RPort->cp_y-RPort->TxBaseline);
  179.       agt_getkey(0);
  180.       Move(RPort,0,RPort->cp_y+RPort->TxBaseline);
  181.       Text(RPort,"          ",10);
  182.       Move(RPort,0,RPort->cp_y-RPort->TxBaseline);
  183.       scroll_count = 0;
  184.     }
  185.   }
  186.  
  187.   curr_x = 0;
  188.   if (script_on) fprintf(scriptfile,"\n");
  189. }
  190.  
  191. void init_interface(void)
  192. {
  193. struct Screen *default_pub_screen;
  194. static WORD screen_pens[] = { -1 };
  195. static struct NewMenu menus[] =
  196.  {{ NM_TITLE,"Project",0,0,0,0 },
  197.   { NM_ITEM,"About...","?",0,0,0 },
  198.   { NM_ITEM,"Quit","Q",0,0,0 },
  199.   { NM_END,0,0,0,0 }};
  200.  
  201.   srand(time(0));
  202.   script_on = 0;
  203.   scriptfile = 0;
  204.   center_on = par_fill_on = 0;
  205.   scroll_count = 0;
  206.   debugfile = stderr;
  207.   DEBUG_OUT = 0;
  208.  
  209.   if (IntuitionBase->lib_Version < 37) exit(0);
  210.  
  211.   if ((default_pub_screen = LockPubScreen(0)) == 0) exit(0);
  212.   if ((Screen = OpenScreenTags(0,
  213.     SA_Pens,screen_pens,
  214.     SA_SysFont,1,
  215.     SA_DisplayID,GetVPModeID(&default_pub_screen->ViewPort),
  216.     SA_Overscan,OSCAN_TEXT,
  217.     SA_Depth,2,
  218.     SA_Type,CUSTOMSCREEN|AUTOSCROLL,
  219.     SA_Title,"AGiliTy",TAG_DONE)) == 0) exit(0);
  220.   UnlockPubScreen(0,default_pub_screen);
  221.  
  222.   if ((Window = OpenWindowTags(0,
  223.     WA_Left,0,
  224.     WA_Top,Screen->BarHeight+1,
  225.     WA_Width,Screen->Width,
  226.     WA_Height,Screen->Height-Screen->BarHeight-1,
  227.     WA_Flags,
  228.       WFLG_ACTIVATE|WFLG_SMART_REFRESH|WFLG_NEWLOOKMENUS|WFLG_BORDERLESS|
  229.       WFLG_BACKDROP,
  230.     WA_IDCMP,IDCMP_VANILLAKEY|IDCMP_RAWKEY|IDCMP_MENUPICK,
  231.     WA_CustomScreen,Screen,TAG_DONE)) == 0) exit(0);
  232.  
  233.   ThisProcess = (struct Process *)FindTask(0);
  234.   OldWindowPtr = ThisProcess->pr_WindowPtr;
  235.   ThisProcess->pr_WindowPtr = Window;
  236.  
  237.   if ((Visual = GetVisualInfo(Screen,TAG_DONE)) == 0) exit(0);
  238.   if ((Menus = CreateMenus(menus,GTMN_NewLookMenus,1,TAG_DONE)) == 0)
  239.     exit(0);
  240.   LayoutMenus(Menus,Visual,GTMN_NewLookMenus,1,TAG_DONE);
  241.   SetMenuStrip(Window,Menus);
  242.  
  243.   RPort = Window->RPort;
  244.   SetDrMd(RPort,JAM2);
  245.   SetAPen(RPort,1);
  246.   SetBPen(RPort,0);
  247.  
  248.   screen_height = Window->Height/RPort->TxHeight;
  249.   screen_width = Window->Width/RPort->TxWidth;
  250.   status_width = screen_width;
  251.   agt_clrscr();
  252. }
  253.  
  254. void close_interface(void)
  255. {
  256.   if (scriptfile != 0) fclose(scriptfile);
  257. }
  258.  
  259. __autoexit void clear_up(void)
  260. {
  261. int i;
  262.  
  263.   for (i = 0; i < HISTORY_SIZE; i++)
  264.     if (History[i] != NULL) FreeVec(History[i]);
  265.   if (FileReq) FreeAslRequest(FileReq);
  266.   if (Menus) FreeMenus(Menus);
  267.   if (Visual) FreeVisualInfo(Visual);
  268.   if (ThisProcess) ThisProcess->pr_WindowPtr = OldWindowPtr;
  269.   if (Window) CloseWindow(Window);
  270.   if (Screen) CloseScreen(Screen);
  271. }
  272.  
  273. int get_character(void)
  274. {
  275. struct IntuiMessage *imsg;
  276. ULONG class;
  277. UWORD code, qualifier;
  278.  
  279. static struct EasyStruct requester =
  280.   { sizeof(struct EasyStruct),0,"AGiliTy",
  281.     "AGiliTy AGT Interpreter 0.3ß\n"
  282.     "© 1996 by Robert Masenten\n\n"
  283.     "Amiga Version by David Kinder","Continue" };
  284.  
  285.   draw_cursor();
  286.   for (;;)
  287.   {
  288.     while (imsg = (struct IntuiMessage *)GetMsg(Window->UserPort))
  289.     {
  290.       class = imsg->Class;
  291.       code = imsg->Code;
  292.       qualifier = imsg->Qualifier;
  293.       ReplyMsg((struct Message *)imsg);
  294.       switch (class)
  295.       {
  296.     case IDCMP_VANILLAKEY:
  297.       draw_cursor();
  298.       return code;
  299.       break;
  300.     case IDCMP_RAWKEY:
  301.       switch (code)
  302.       {
  303.         case 0x4C:
  304.           draw_cursor();
  305.           return CHAR_UP;
  306.           break;
  307.         case 0x4D:
  308.           draw_cursor();
  309.           return CHAR_DOWN;
  310.           break;
  311.         case 0x4E:
  312.           draw_cursor();
  313.           return (qualifier & SHIFT) ? CHAR_SHIFTRIGHT : CHAR_RIGHT;
  314.           break;
  315.         case 0x4F:
  316.           draw_cursor();
  317.           return (qualifier & SHIFT) ? CHAR_SHIFTLEFT : CHAR_LEFT;
  318.           break;
  319.       }
  320.       break;
  321.     case IDCMP_MENUPICK:
  322.       if (MENUNUM(code) == 0)
  323.       {
  324.         switch (ITEMNUM(code))
  325.          {
  326.           case 0:
  327.         busy_pointer(1);
  328.         EasyRequest(Window,&requester,0);
  329.         busy_pointer(0);
  330.         break;
  331.           case 1:
  332.         exit(0);
  333.         break;
  334.         }
  335.       }
  336.       break;
  337.       }
  338.     }
  339.     WaitPort(Window->UserPort);
  340.   }
  341. }
  342.  
  343. void busy_pointer(int busy)
  344. {
  345.   if (IntuitionBase->lib_Version >= 39)
  346.     SetWindowPointer(Window,WA_BusyPointer,busy,TAG_DONE);
  347. }
  348.  
  349. void draw_cursor(void)
  350. {
  351.   SetDrMd(RPort,COMPLEMENT);
  352.   RectFill(RPort,
  353.     RPort->cp_x,RPort->cp_y,
  354.     RPort->cp_x+RPort->TxWidth-1,RPort->cp_y+RPort->TxHeight-1);
  355.   SetDrMd(RPort,JAM2);
  356. }
  357.  
  358. void get_string(char *buffer, int len)
  359. {
  360. int c, end = 0, cursor = 0, hpos = -1;
  361. char co;
  362. UWORD left;
  363.  
  364.   *buffer = '\0';
  365.   left = RPort->cp_x;
  366.   SetAPen(RPort,2);
  367.   for (;;)
  368.   {
  369.     c = get_character();
  370.     switch (c)
  371.     {
  372.       case 0x0D:
  373.     *(buffer+end) = '\0';
  374.     add_history(buffer);
  375.     *(buffer+end) = '\n';
  376.     *(buffer+end+1) = '\0';
  377.     SetAPen(RPort,1);
  378.     return;
  379.     break;
  380.       case 0x7F:
  381.     if ((end > 0) && (cursor < end))
  382.     {
  383.       memmove(buffer+cursor,buffer+cursor+1,end-cursor+1);
  384.       ClipBlit(RPort,RPort->cp_x+RPort->TxWidth,RPort->cp_y,
  385.         RPort,RPort->cp_x,RPort->cp_y,
  386.         Window->Width-RPort->cp_x-RPort->TxWidth,
  387.         RPort->TxHeight,0xC0);
  388.       end--;
  389.     }
  390.     break;
  391.       case 0x08:
  392.     if ((end > 0) && (cursor > 0))
  393.     {
  394.       memmove(buffer+cursor-1,buffer+cursor,end-cursor+1);
  395.       ClipBlit(RPort,RPort->cp_x,RPort->cp_y,
  396.         RPort,RPort->cp_x-RPort->TxWidth,RPort->cp_y,
  397.         Window->Width-RPort->cp_x-RPort->TxWidth,
  398.         RPort->TxHeight,0xC0);
  399.       Move(RPort,RPort->cp_x-RPort->TxWidth,RPort->cp_y);
  400.       end--;
  401.       cursor--;
  402.     }
  403.     break;
  404.       case CHAR_LEFT:
  405.     if (cursor > 0)
  406.     {
  407.       cursor--;
  408.       Move(RPort,RPort->cp_x-RPort->TxWidth,RPort->cp_y);
  409.     }
  410.     break;
  411.       case CHAR_SHIFTLEFT:
  412.     if (cursor > 0)
  413.     {
  414.       Move(RPort,left,RPort->cp_y);
  415.       cursor = 0;
  416.     }
  417.     break;
  418.       case CHAR_RIGHT:
  419.     if (cursor < end)
  420.     {
  421.       cursor++;
  422.       Move(RPort,RPort->cp_x+RPort->TxHeight,RPort->cp_y);
  423.     }
  424.     break;
  425.       case CHAR_SHIFTRIGHT:
  426.     if (cursor < end)
  427.     {
  428.       Move(RPort,RPort->cp_x+(RPort->TxWidth*(end-cursor)),RPort->cp_y);
  429.       cursor = end;
  430.     }
  431.     break;
  432.       case CHAR_UP:
  433.     if ((hpos < HISTORY_SIZE-1) && (History[hpos+1]))
  434.       cursor = end = use_history(buffer,++hpos,left);
  435.     break;
  436.       case CHAR_DOWN:
  437.     if ((hpos > 0) && (History[hpos-1]))
  438.       cursor = end = use_history(buffer,--hpos,left);
  439.     else
  440.       cursor = end = use_history(buffer,-1,left);
  441.     break;
  442.       default:
  443.     if ((end < len-3) && (isprint((unsigned char)c) != 0) && ( c < 128)
  444.       && (RPort->cp_x+(RPort->TxWidth*(end-cursor+2)) < Window->Width))
  445.     {
  446.       memmove(buffer+cursor+1,buffer+cursor,end-cursor+1);
  447.       *(buffer+cursor++) = c;
  448.       ClipBlit(RPort,RPort->cp_x,RPort->cp_y,
  449.         RPort,RPort->cp_x+RPort->TxWidth,RPort->cp_y,
  450.         Window->Width-RPort->cp_x-RPort->TxWidth,
  451.         RPort->TxHeight,0xC0);
  452.       end++;
  453.       Move(RPort,RPort->cp_x,RPort->cp_y+RPort->TxBaseline);
  454.       co = c;
  455.       Text(RPort,&co,1);
  456.       Move(RPort,RPort->cp_x,RPort->cp_y-RPort->TxBaseline);
  457.     }
  458.     break;
  459.     }
  460.   }
  461. }
  462.  
  463. void add_history(char *buffer)
  464. {
  465. char *hist;
  466. int i;
  467.  
  468.   if (strcmp(buffer,"") == 0) return;
  469.   if ((hist = AllocVec(strlen(buffer)+1,MEMF_CLEAR)) == NULL) return;
  470.   strncpy(hist,buffer,strlen(buffer));
  471.   if (History[HISTORY_SIZE-1] != NULL) FreeVec(History[HISTORY_SIZE-1]);
  472.   for (i = HISTORY_SIZE-1; i > 0; i--) History[i] = History[i-1];
  473.   History[0] = hist;
  474. }
  475.  
  476. int use_history(char *buffer, int hpos, int left)
  477. {
  478.   strcpy(buffer,(hpos > -1) ? History[hpos] : "");
  479.   SetAPen(RPort,0);
  480.   RectFill(RPort,left,RPort->cp_y,
  481.     Window->Width-1,RPort->cp_y+RPort->TxHeight-1);
  482.   SetAPen(RPort,2);
  483.   Move(RPort,left,RPort->cp_y);
  484.   agt_puts(buffer);
  485.   return strlen(buffer);
  486. }
  487.  
  488. void file_req(char *s,char *title,char *pattern,char *dir,ULONG save)
  489. {
  490.   if (FileReq == NULL)
  491.   {
  492.     if ((FileReq = AllocAslRequestTags(ASL_FileRequest,
  493.       ASLFR_SleepWindow,1,
  494.       ASLFR_RejectIcons,1,
  495.       ASLFR_InitialDrawer,dir,TAG_DONE)) == NULL) exit(0);
  496.   }
  497.   if (AslRequestTags(FileReq,
  498.     ASLFR_Window,Window,
  499.     ASLFR_DoPatterns,pattern == NULL ? 0 : 1,
  500.     ASLFR_InitialPattern,pattern == NULL ? "#?" : pattern,
  501.     ASLFR_InitialFile,"",
  502.     ASLFR_TitleText,title,
  503.     ASLFR_DoSaveMode,save,TAG_DONE))
  504.   {
  505.     strcpy(s,FileReq->fr_Drawer);
  506.     AddPart(s,FileReq->fr_File,256);
  507.   }
  508.   else strcpy(s,"");
  509. }
  510.  
  511. wbmain(struct WBStartup *wb_msg)
  512. {
  513. struct DiskObject *icon;
  514. char file_name[256], start_dir[256];
  515. char *args[2], *dir, *file, *ext;
  516.  
  517.   args[0] = wb_msg->sm_ArgList[0].wa_Name;
  518.   args[1] = file_name;
  519.   strcpy(start_dir,"");
  520.  
  521.   if (icon = GetDiskObject(args[0]))
  522.   {
  523.     if (dir = FindToolType(icon->do_ToolTypes,"DIR")) strcpy(start_dir,dir);
  524.     FreeDiskObject(icon);
  525.   }
  526.  
  527.   file_req(file_name,"Select an AGT Game","#?.da1",start_dir,0);
  528.  
  529.   file = FilePart(file_name);
  530.   if (ext = strrchr(file,'.')) *ext = '\0';
  531.  
  532.   main(2,args);
  533.   exit(0);
  534. }
  535.  
  536. FILE *get_user_file(int ft)
  537. {
  538. char *fname, *otype, *title;
  539. char *p, *q;
  540. int save;
  541. FILE *fd;
  542.  
  543.   switch (ft)
  544.   {
  545.     case 0:
  546.       title = "Script File";
  547.       save = 1;
  548.       otype = "a";
  549.       break;
  550.     case 1:
  551.       title = "Save Game";
  552.       save = 1;
  553.       otype = "wb";
  554.       break;
  555.     case 2:
  556.       title = "Restore Game";
  557.       save = 0;
  558.       otype = "rb";
  559.       break;
  560.     case 3:
  561.       title = "Read Log";
  562.       save = 0;
  563.       otype = "r";
  564.       break;
  565.     case 4:
  566.       title = "Write Log";
  567.       save = 1;
  568.       otype = "w";
  569.       break;
  570.     default:
  571.       writeln("<INT ERR: invalid file type>");
  572.       return NULL;
  573.   }
  574.  
  575.   fname = rmalloc(256);
  576.   file_req(fname,title,NULL,"",save);
  577.  
  578.   for(p = fname; isspace(*p); p++);
  579.   for(q = fname; *p!=0; p++, q++) *q=*p;
  580.   *q = 0;
  581.  
  582.   if (q==fname)
  583.   {
  584.     writeln("Never mind.");
  585.     rfree(fname);
  586.     return NULL;
  587.   }
  588.  
  589.   if (otype[0] == 'w')
  590.   {
  591.     fd = fopen(fname,"r");
  592.     if (fd)
  593.     {
  594.       fclose(fd);
  595.       if (!yesno("This file already exists; overwrite?"))
  596.       {
  597.     rfree(fname);
  598.     return NULL;
  599.       }
  600.     }
  601.   }
  602.  
  603.   fd = fopen(fname,otype);
  604.   if (fd == NULL) writeln("Cannot open file.");
  605.   rfree(fname);
  606.   return fd;
  607. }
  608.  
  609. bool agt_option(int optnum, char *optstr[], bool setflag)
  610. {
  611.   return 0; 
  612. }
  613.  
  614. FILE *agt_globalfile(int fid)
  615. {
  616.   if (fid == 0)
  617.     return fopen("agil.cfg","r");
  618.  
  619.   return NULL;
  620. }
  621.  
  622. void agt_makebox(int width, int height, unsigned long flags)
  623. {
  624.   box = 1;
  625.   boxx = flags & TB_NOCENT ? 0 : ((screen_width-width)/2)*RPort->TxWidth;
  626.   if (flags & TB_TTL)
  627.     Move(RPort,boxx,(((screen_height-height)/4)*RPort->TxHeight));
  628.   else
  629.     Move(RPort,boxx,RPort->cp_y-(screen_height-height)*RPort->TxHeight);
  630. }
  631.  
  632. void agt_qnewline(void)
  633. {
  634.   agt_newline();
  635. }
  636.  
  637. void agt_endbox(void)
  638. {
  639.   box = 0;
  640.   boxx = 0;
  641.   agt_newline();
  642. }
  643.